package cn.codesugar.videocache

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.SeekBar
import androidx.fragment.app.Fragment
import cn.codesugar.videocache.databinding.FragmentVideoBinding
import com.danikula.videocache.CacheListener
import com.danikula.videocache.ProxyCacheManager
import java.io.File

private const val URL = "url"
class GalleryVideoFragment : Fragment(), CacheListener {

    private var _binding: FragmentVideoBinding? = null
    private val binding get() = _binding!!
    private var url: String? = null
    private val updater: VideoProgressUpdater = VideoProgressUpdater()
    private var visibleForUser = false
    private var playerStarted = false
    private var position = 0

    companion object {
        @JvmStatic
        fun newInstance(url: String) =
            GalleryVideoFragment().apply {
                arguments = Bundle().apply {
                    putString(URL, url)
                }
            }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            url = it.getString(URL)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentVideoBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        startProxy()
        checkCachedState()
        Log.d(TAG, "onViewCreated - $visibleForUser")
        if (visibleForUser) {
            Log.d(TAG, "onViewCreated - startPlayer()")
            startPlayer()
        }
        binding.progressBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {

            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {}

            override fun onStartTrackingTouch(seekBar: SeekBar?) {}

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                binding.videoView.apply {
                    val videoPosition: Int = duration * binding.progressBar.progress / 100
                    seekTo(videoPosition)
                }
            }

        })
    }

    override fun onCacheAvailable(cacheFile: File?, url: String?, percentsAvailable: Int) {
        binding.progressBar.secondaryProgress = percentsAvailable
        setCachedState(percentsAvailable == 100)
    }

    override fun onStart() {
        super.onStart()
        Log.d(TAG, "onStart()")
    }

    override fun onResume() {
        super.onResume()
        Log.d(TAG, "onResume()")
        startPlayer()
        updater.start()
    }

    override fun onPause() {
        super.onPause()
        Log.d(TAG, "onPause()")
        if (playerStarted) {
            position = binding.videoView.currentPosition
            binding.videoView.pause()
        }
        updater.stop()
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "onDestroy()")
        binding.videoView.stopPlayback()
        ProxyCacheManager.getProxy(requireContext()).unregisterCacheListener(this)
    }

    private fun startPlayer() {
        binding.videoView.seekTo(position)
        binding.videoView.start()
        playerStarted = true
    }

    private fun updateVideoProgress() {
        val videoProgress: Int = binding.videoView.currentPosition * 100 / binding.videoView.duration
        binding.progressBar.progress = videoProgress
    }

    private fun startProxy() {
        val proxy = ProxyCacheManager.getProxy(requireContext())
        proxy.registerCacheListener(this, url)
        val proxyUrl = proxy.getProxyUrl(url)
        Log.d(TAG, "使用代理网址 $proxyUrl 而不是原始网址 $url")
        binding.videoView.setVideoPath(proxy.getProxyUrl(url))
    }

    private fun checkCachedState() {
        val proxy = ProxyCacheManager.getProxy(requireContext())
        val fullyCached = proxy.isCached(url)
        setCachedState(fullyCached)
        if (fullyCached) {
            binding.progressBar.secondaryProgress = 100
        }
    }

    private fun setCachedState(cached: Boolean) {
        val statusIconId = if (cached) R.drawable.ic_cloud_done else R.drawable.ic_cloud_download
        binding.cacheStatusImageView.setImageResource(statusIconId)
    }

    inner class VideoProgressUpdater : Handler(Looper.getMainLooper()) {
        fun start() {
            sendEmptyMessage(0)
        }

        fun stop() {
            removeMessages(0)
        }

        override fun handleMessage(msg: Message) {
            updateVideoProgress()
            sendEmptyMessageDelayed(0, 500)
        }
    }
}